package com.csust.automaticteach.app.teacher.multimodal;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesis;
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesisParam;
import com.alibaba.dashscope.aigc.videosynthesis.VideoSynthesisResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.JsonUtils;
import com.csust.automaticteach.exception.BusinessException;
import com.csust.automaticteach.exception.ErrorCode;
import com.csust.automaticteach.exception.ThrowUtils;
import com.csust.automaticteach.model.dto.multimodalgen.GenVideoRequest;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassNamePictureGenerateApp
 * @Description 视频生成app
 * @Author钰玟
 * @Date2025/8/5 下午8:00
 * @Version 1.0
 **/

@Service
@Slf4j
public class VideoGenerateApp {
    @Resource
    private MultiModalGenerateConfig multiModalGenerateConfig;

    /**
     * Create a video compositing task and wait for the task to complete.
     */
    public VideoSynthesisResult text2Video(GenVideoRequest request) throws ApiException, NoApiKeyException, InputRequiredException {
        VideoSynthesis vs = new VideoSynthesis();
        VideoSynthesisParam param =
                VideoSynthesisParam.builder()
                        .apiKey(multiModalGenerateConfig.getApiKey())
                        .model(multiModalGenerateConfig.getTextingVideoModel())
                        .prompt(request.getPrompt())
                        .size(request.getResolution())
                        .build();

        // 异步调用
        VideoSynthesisResult task = vs.asyncCall(param);
        log.info(JsonUtils.toJson(task));
        //获取结果
        // apiKey 已经配置在环境变量，因此这里可以设置为 null
        VideoSynthesisResult result = vs.wait(task, multiModalGenerateConfig.getApiKey());
        log.info(JsonUtils.toJson(result));
        return result;
    }

    /**
     * 图生视频
     *
     * @param request 请求参数
     * @return 视频合成结果
     * @throws ApiException
     * @throws NoApiKeyException
     * @throws InputRequiredException
     */
    public VideoSynthesisResult image2video(GenVideoRequest request) throws ApiException, NoApiKeyException, InputRequiredException {
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("prompt_extend", true);
        //是否自定义了视频的分辨率
        if (StrUtil.isNotBlank(request.getResolution())) {
            parameters.put("resolution", request.getResolution());
        }
        //处理图片文件路径   统一转成正斜杠，并拼成 file:// URL
        String absPath = request.getImgUrl().replace('\\', '/');
        String imgUrl = "file://" + (absPath.startsWith("/") ? "" : "/") + absPath;
        VideoSynthesis vs = new VideoSynthesis();
        VideoSynthesisParam param =
                VideoSynthesisParam.builder()
                        .apiKey(multiModalGenerateConfig.getApiKey())
                        .model(multiModalGenerateConfig.getPicturingVideoModel())
                        .prompt(request.getPrompt())
                        .imgUrl(imgUrl)
                        .parameters(parameters)
                        .build();
        // 异步调用
        VideoSynthesisResult task = vs.asyncCall(param);
        log.info(JsonUtils.toJson(task));
        //获取结果
        VideoSynthesisResult result = vs.wait(task, multiModalGenerateConfig.getApiKey());
        //清理资源
        if ("SUCCEEDED".equals(result.getOutput().getTaskStatus())) {
            Boolean deleted = this.deleteFile(request.getImgUrl());
            log.info("清理资源图片结果：{}", deleted);
        }
        log.info(JsonUtils.toJson(result));
        return result;
    }

    /**
     * 根据绝对路径删除文件/空目录
     *
     * @param absolutePath 绝对路径
     * @return 删除结果
     */
    public Boolean deleteFile(String absolutePath) {
        ThrowUtils.throwIf(StrUtil.isBlank(absolutePath), ErrorCode.PARAMS_ERROR);
        File file = new File(absolutePath);
        // 1. 是否存在
        if (!file.exists()) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "文件不存在");
        }
        // 2. 安全校验：只允许删除项目根目录/tmp/gen下的文件
        String rootPath = System.getProperty("user.dir");
        String allowedPrefix = new File(rootPath, "tmp/gen").getAbsolutePath();
        if (!file.getAbsolutePath().startsWith(allowedPrefix)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "非法路径，禁止删除");
        }
        // 3. Hutool 删除（文件或空目录均可）
        boolean success = FileUtil.del(file);
        ThrowUtils.throwIf(!success, ErrorCode.SYSTEM_ERROR, "删除失败");
        return true;
    }

}
